package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.ScanUser;
import com.example.demo.exception.SXException;
import com.example.demo.mapper.ScanUserMapper;
import com.example.demo.service.ScanUserService;
import com.example.demo.utils.FileUtil;
import com.example.demo.utils.IdGenerate;
import com.example.demo.utils.ScanUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Date;

/**
 * <p>
 * 扫脸库用户信息表 服务实现类
 * </p>
 *
 * @author lst
 * @since 2019-12-18
 */
@Service
public class ScanUserServiceImpl implements ScanUserService {

    private static Logger logger = LoggerFactory.getLogger(ScanUserServiceImpl.class);

    @Autowired
    private ScanUserMapper scanUserMapper;

    //本地测试使用的文件夹
    @Value("${fileconf.userFilesPath}")
    private String userFilesPath;

    //临时目录文件夹
    @Value("${fileconf.userFilesPathTemp}")
    private String userFilesPathTemp;

    @Value("${scanconf.groupId}")
    private String GROUP_ID;

    /**
     * 人脸注册
     * @param file 文件
     * @return String
     * @author lst
     * @since 2019-12-18
     */
    @Override
    @Transactional
    public String resisterFace(MultipartFile file) {
        //先将文件上传到服务器路径
        String fileName = file.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        String saveFileName = FileUtil.getFileName(suffix);

        try {
            //上传文件到本地服务器
            if (!FileUtil.saveFile(userFilesPath + File.separator, saveFileName, file.getInputStream())) {
                logger.info("文件上传失败");
                return "注册失败，内部错误请联系管理员";
            }
            //实际保存到服务器上的图片路径
            String filePath = userFilesPath + saveFileName;
            ScanUser insertUser = new ScanUser();
            String userId = IdGenerate.generateId();
            //调用百度的人脸识别的注册接口
            JSONObject jsonObject = new ScanUtils().doRegister(filePath, userId, GROUP_ID);
            //注册成功的图片保存在百度人脸库中的唯一标识
            String faceToken = jsonObject.getJSONObject("result").getString("face_token");

            //如果之前用户已经注册过，则需做更新操作
            QueryWrapper<ScanUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("face_token", faceToken);
            ScanUser dbUser = scanUserMapper.selectOne(queryWrapper);
            if (dbUser != null) {
                dbUser.setImageUrl(filePath);
                dbUser.setFaceToken(faceToken);
                dbUser.setUpdateDate(new Date());
                scanUserMapper.updateById(dbUser);
                return userId;
            }
            //没有注册过，则重新注册
            insertUser.setFaceToken(faceToken);
            insertUser.setId(userId);
            insertUser.setGroupId(GROUP_ID);
            insertUser.setImageUrl(filePath);
            insertUser.setUserInfo("用户扫脸注册的信息");
            insertUser.setCreateBy(userId);
            insertUser.setUpdateBy(userId);
            insertUser.setCreateDate(new Date());
            insertUser.setUpdateDate(new Date());
            insertUser.setDelFlag("0");
            scanUserMapper.insert(insertUser);
            return userId;
        } catch (Exception e) {
            logger.error("文件上传失败");
            return "注册失败";
        }
    }

    /**
     * 人脸对比
     * @param file 文件
     * @param userId 用户ID
     * @return String
     * @author lst
     * @since 2019-12-18
     */
    @Override
    public String compareFace(MultipartFile file, String userId) {
        String newImagePath = getFilePath(file);
        ScanUser dbUser = scanUserMapper.selectById(userId);
        String oldImagePath = dbUser.getImageUrl();
        JSONObject object = new ScanUtils().compareFace(newImagePath, oldImagePath);
        //获取对比的分数
        Double compareScore = object.getJSONObject("result").getDouble("score");
        //对比过后将删除临时文件夹的图片
        deleteTempFile(userFilesPathTemp);
        if (compareScore > 95) {
            return "success";
        }
        return "fail";
    }

    /**
     * 获取上传后的文件路径
     * @param file
     * @return String
     */
    public String getFilePath(MultipartFile file) {
        //先将文件上传到服务器路径
        String fileName = file.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        String saveFileName = FileUtil.getFileName(suffix);
        try {
            //上传文件到本地服务器
            boolean flag = FileUtil.saveFile(userFilesPathTemp + File.separator, saveFileName, file.getInputStream());
            if (!flag) {
                return "注册失败，内部错误请联系管理员";
            }
            //实际保存到服务器上的图片路径
            return userFilesPathTemp + saveFileName;
        } catch (Exception e) {
            logger.error("文件上传失败，请检查：{}",e.toString());
            throw new SXException("文件上传失败，请检查");
        }
    }

    /**
     * 删除某文件夹下上传的临时文件
     *
     * @param temPath
     */
    public void deleteTempFile(String temPath) {
        File ff = new File(temPath);
        //数组指向文件夹中的文件和文件夹
        File[] fi = ff.listFiles();
        //遍历文件和文件夹
        for (File file : fi) {
            file.delete();
        }
    }


}
